package com.stars.questions.deptQuestion.publish.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.stars.base.entity.Result;
import com.stars.questions.deptQuestion.common.entity.CommonConstants;
import com.stars.questions.deptQuestion.config.entity.Question;
import com.stars.questions.deptQuestion.config.entity.QuestionSub;
import com.stars.questions.deptQuestion.config.service.QuestionConfigService;
import com.stars.questions.deptQuestion.publish.entity.Reply;
import com.stars.questions.deptQuestion.publish.entity.ReplySub;
import com.stars.questions.deptQuestion.publish.mapper.PublishMapper;
import com.stars.questions.deptQuestion.publish.mapper.ReplySubMapper;
import com.stars.questions.deptQuestion.publish.service.PublishService;
import com.stars.util.cache.CacheUtil;
import com.stars.util.common.DevelopKit;
import com.stars.util.common.IpLocalUtil;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;


@Service
public class PublishServiceImpl implements PublishService {

    private final CacheUtil cacheUtil;
    private final QuestionConfigService configService;

    private final SqlSessionFactory sqlSessionFactory;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    public static Integer SUBMIT_BETWEEN_SECOND = 10*1000;//两次提交间隔时间 秒

    public PublishServiceImpl(CacheUtil cacheUtil, QuestionConfigService configService, SqlSessionFactory sqlSessionFactory) {
        this.cacheUtil = cacheUtil;
        this.configService = configService;
        this.sqlSessionFactory = sqlSessionFactory;
    }


    @Override
    public JSONObject loadQuestion() {
        JSONObject result = new JSONObject();
        result.put("result",false);

        Question question = configService.getPublishQuestion();

        if(question == null){
            result.put("msg","调查问卷尚未开始！");
            return result;
        }
        if(!StringUtils.hasLength(question.getId())){
            result.put("msg","调查问卷获取失败！");
            return result;
        }

        List<QuestionSub> list = cacheUtil.getValueByList(CommonConstants.PUBLISH_QUESTION_PREFIX + question.getId(), QuestionSub.class);

        if(list==null||list.size()==0){
            list = configService.loadQuestionSub(question.getId(),question.getMark());
            cacheUtil.setValue(CommonConstants.PUBLISH_QUESTION_PREFIX + question.getId(),list);
        }
        Set<Integer> set = configService.generateRandomNum(question,list.size());
        List<QuestionSub> relist;
        if(set==null){
            relist = list;
        }else{
            relist = new ArrayList<>();
            for(Integer index : set){
                relist.add(list.get(index));
            }
        }

        result.put("result",true);
        result.put("array",relist);
        result.put("questionConfig",question);

        return result;
    }

    @Override
    public Result saveReply(HttpServletRequest request, Reply reply) {

        HttpSession session = request.getSession();
        String ip = IpLocalUtil.getIPAddress(request);
        reply.setIp(ip);
        // 问卷配置id
        String configId = reply.getConfigId();


        boolean checkSubmit = configService.checkSubmit(reply);
        if(checkSubmit){
            logger.error("【问卷】提交失败，该手机号已经提交过问卷:[{}]，configId:[{}]",ip,configId);
            return Result.error("提交失败，该手机号已经提交过问卷。");
        }

        if(!StringUtils.hasLength(configId)){
            logger.error("【问卷】提交失败，未获取到问卷设置表单ip:[{}]，configId:[{}]",ip,configId);
            return Result.error("提交失败，未找到要提交的问卷信息。");
        }

        //提交次数限制
        Date lastSaveTime = (Date) session.getAttribute("lastSaveTime");
        if(lastSaveTime !=null && (System.currentTimeMillis()-lastSaveTime.getTime())< SUBMIT_BETWEEN_SECOND){
            logger.error("【问卷】操作过于频繁，提交ip:[{}]",ip);
            return Result.error("操作过于频繁。");
        }
        session.setAttribute("lastSaveTime",new Date());

        //是否存在，是否发布和超过时间范围
        Question question = configService.loadQuestion(configId);
        if(question==null){
            logger.error("【问卷】提交失败，未找到要提交的问卷信息ip:[{}]，configId:[{}]",ip,configId);
            return Result.error("提交失败，未找到要提交的问卷信息。");
        }

        if(question.getPublish()!=1 || question.getStartDate()==null || question.getEndDate()==null
                || new Date().getTime()<question.getStartDate().getTime()
                || new Date().getTime()>question.getEndDate().getTime()){
            logger.error("【问卷】提交失败，调查问卷尚未开始ip:[{}]，configId:[{}]，开始时间startDate:[{}]，结束时间endDate:[{}]",ip,configId,question.getStartDate(),question.getEndDate());
            return Result.error("提交失败，问卷调查尚未开始。");
        }

        boolean result = true;
        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
        PublishMapper publishMapper = sqlSession.getMapper(PublishMapper.class);
        ReplySubMapper replySubMapper = sqlSession.getMapper(ReplySubMapper.class);
        try {
            //保存主表
            String replyId = DevelopKit.generateUUID();
            reply.setId(replyId);
            reply.setCreateDate(new Date());
            reply.setAgent(request.getHeader("User-Agent"));
            DevelopKit.setBaseInfo(reply);

            publishMapper.insert(reply);
            //保存子表
            List<ReplySub> subList = reply.getQuestions();

            for (ReplySub sub : subList) {
                sub.setId(DevelopKit.generateUUID());
                sub.setFid(replyId);
                DevelopKit.setBaseInfo(sub);

                replySubMapper.insert(sub);
            }
            // 提交
            sqlSession.commit();

        }catch (Exception e){
            e.printStackTrace();
            sqlSession.rollback();
            result = false;
        }finally {
            try {
                sqlSession.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if(!result){
            return Result.error("数据提交失败，请检查填写的信息。");
        }

        //提交成功重设key值
        session.setAttribute("key","0");

        return Result.success();
    }
}
